% Copyright 2020 Makani Technologies LLC
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
%      http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.

function [ plot_struct ] = StackList( plot_str )
%STACKLIST Function for generating list of plots for PlotStacking
%   StackList generates a cell array that provides plot directives to
%   PlotStacking.
%
% Arguments
%
% plot_str: Cell array of desired plot groups.
%
% Return values
%
% plot_struct: Structure containing directives for PlotStacking
%
% Required toolboxes: None.

%% Set up defaults
if (nargin < 1)
  plot_str = 'all';
end

% Initialize struct
plot_struct = [];

if (contains({'control', 'isr', '15kHz'}, plot_str))

% TODO: It has been useful in the past to be able to tune the time offsets of
% motors relative to each other to reflect different trigger times.  It may have
% to be a tweak in the GetMotorMessages call rather than part of the plot
% description.
  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'error', 'errors', 'Error Number', [], ...
                        false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'warning', 'warning', 'Warning Number', [], ...
                        false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'v_{bus}', 'motor_state_v_bus', 'Voltage (V)', [], ...
                        false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'i_{bus}', 'motor_state_i_bus', 'Current (A)', [], ...
                        false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'omega_cmd', {'omega_lower_limit', 'omega_upper_limit'}, ...
                        'Rot. Velocity (rad/sec)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'omega', 'motor_state_omega_mech', ...
                        'Rot. Velocity (rad/sec)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'theta_e', 'motor_state_theta_elec', ...
                        'Rot. Angle (rad)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'i_d', ...
                        {'foc_current_actual_id', 'foc_current_desired_id'}, ...
                        'Current (A)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'i_q', ...
                        {'foc_current_actual_iq', 'foc_current_desired_iq'}, ...
                        'Current (A)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'i0', ...
                        {'foc_current_actual_i0', 'foc_current_desired_i0'}, ...
                        'Current (A)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'state id integrator', 'foc_state_id_int', ...
                        'Current (A)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'state iq integrator', 'foc_state_iq_int', ...
                        'Current (A)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'state id error last', 'foc_state_id_error_last', ...
                        'Current (A)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'state iq error last', 'foc_state_iq_error_last', ...
                        'Current (A)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'v_{ref}', 'foc_voltage_v_ref', ...
                        'Voltage (V)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'v_{angle}', 'foc_voltage_angle', ...
                        'Angle (rad)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'v_{q}', 'foc_voltage_vq', ...
                        'Voltage (V)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'v_{d}', 'foc_voltage_vd', ...
                        'Voltage (V)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorIsrLog', 'PlotMotorData', ...
                        [], 'i_{abc}', ...
                        {'motor_state_ia', 'motor_state_ib', 'motor_state_ic'}, ...
                        'Current (A)', [], false, [], plot_struct);
end

if (contains({'high_speed', 'stacking','debug','alignfault','all'}, plot_str))

  %% Generate high speed Plots
  % Motor status
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Motor Status', 'motor_status', ...
                        'Status (bits)', [], false, [], plot_struct);

  % Errors
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Motor Error', 'motor_error', 'Error', ...
                        [], false, [], plot_struct);

  % Warnings
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Motor Warnings', 'motor_warning', 'Warning', ...
                        [], false, [], plot_struct);

  % Voltage
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Voltage', 'bus_voltage', 'Voltage (V)', ...
                        [], false, [], plot_struct);

  % Voltage mean for stacking
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Voltage Mean', 'voltage_stack_mean', ...
                        'Voltage (V)', [], false, [], plot_struct);

  % Abs diff of Voltage mean for stacking
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        7, 'abs(Diff Voltage Mean)', 'voltage_stack_mean', ...
                        'Voltage Delta (V)', [], false, [], plot_struct);

  % Voltage with bias removed
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        4, 'Voltage (bias removed)', ...
                        {'bus_voltage', 'voltage_pair_bias'}, 'Voltage (V)', ...
                        [], false, [], plot_struct);

  % Voltage slope
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        7, 'abs(Voltage diff)', 'bus_voltage', ...
                        'Voltage Delta (V)', [], false, [], plot_struct);

  % Speed
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Speed', 'omega', 'Omega (rad/sec)', ...
                        [], false, [], plot_struct);
end

if (contains({'high_speed', 'stacking','debug','all'}, plot_str))
  % Voltage with filtering
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        1, 'Filtered Voltage', 'bus_voltage', 'Voltage (V)', ...
                        [], false, [], plot_struct);

  % Voltage Sum
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        [], 'Voltage Sum', 'bus_voltage', 'Voltage (V)', ...
                        [], false, [], plot_struct);

  % Plot individual powers
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        1, 'Motor Power (Filtered at 10 Hz)', 'power', ...
                        'Power (W)', {'@(x,y) x.*y', {'bus_voltage', 'bus_current'}, ...
                        'power', []}, false, [], plot_struct);

  % Power Sum
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        3, 'Power Sum (Filtered at 20 Hz)', 'power', ...
                        'Power (W)', {'@(x,y) x.*y', {'bus_voltage', 'bus_current'}, ...
                        'power', []}, false, [], plot_struct);

  % Power Sum Top vs bottom
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        4, 'Power Sum Top vs Bottom', 'power', ...
                        'Power (W)', {'@(x,y) x.*y', {'bus_voltage', 'bus_current'}, ...
                        'power', []}, false, [], plot_struct);

  % Power Sum Starboard and Port
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        5, 'Power Starboard vs Port (Filtered at 20 Hz)', 'power', ...
                        'Power (W)', {'@(x,y) x.*y', {'bus_voltage', 'bus_current'}, ...
                        'power', []}, false, [], plot_struct);

  % Voltage differences across pairs
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorDiffData', ...
                        [], 'Voltage Pair Differences', 'bus_voltage', ...
                        'Voltage (V)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Voltage Pair Bias', 'voltage_pair_bias', ...
                        'Voltage (V)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Speed Command', ...
                        {'omega_upper_limit', 'omega_lower_limit'}, ...
                        'Speed Command (rad/sec)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Torque Command', 'torque_cmd', ...
                        'Torque Command (Nm)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Speed Correction', 'speed_correction', ...
                        'Speed Correction (rad/sec)', [], false, [], plot_struct);

  %% Temporary plots for stacking sum testing
  % Create speed_corr_sign which is speed_correction modified for spin direction
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        3, 'Speed Correction Net', 'speed_corr_sign', ...
                        'Speed Correction (rad/sec)', ...
                        {'@(x,y) sign(x).*y', {'omega', 'speed_correction'}, ...
                        'speed_corr_sign', []}, ...
                        false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        4, 'Speed Correction Top vs Bottom', 'speed_corr_sign', ...
                        'Speed Correction (rad/sec)', ...
                        {'@(x,y) sign(x).*y', {'omega', 'speed_correction'}, ...
                        'speed_corr_sign', []}, ...
                        false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        5, 'Speed Correction Starboard vs Port', 'speed_corr_sign', ...
                        'Speed Correction (rad/sec)', ...
                        {'@(x,y) sign(x).*y', {'omega', 'speed_correction'}, ...
                        'speed_corr_sign', []}, ...
                        false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        3, 'Current Correction Net', 'current_correction', ...
                        'Current (A)', ...
                        [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        4, 'Current Correction Top vs Bottom', 'current_correction', ...
                        'Current (A)', ...
                        [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        5, 'Current Correction Starboard vs Port', 'current_correction', ...
                        'Current (A)', ...
                        [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        6, 'Double Rainbox Iq sum', 'iq', ...
                        'Iq (Amps)', [], ...
                        false, [], plot_struct);


  %% End of temporary section
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Current Correction', 'current_correction', ...
                        'Current (A)', ...
                        [], false, [], plot_struct);

  % Gated sum of current corrections
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        1, 'Sum of Current Corrections', 'current_correction', ...
                        'Current (A)', ...
                        [], false, [], plot_struct);

  % Filtered Speed
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        1, 'Speed (filtered)', 'omega', ...
                        '\omega (filtered) (rad/s)', ...
                        [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'iq (command residual)', 'iq_cmd_residual', ...
                        'i_q (A)', ...
                        [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'i_{bus} (upper limit)', 'iq_upper_limit', ...
                        'i_{bus} (Amps)', ...
                        [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'i_{bus} (lower limit)', 'iq_lower_limit', ...
                        'i_{bus} (Amps)', ...
                        [], false, [], plot_struct);

  % i_q
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'iq', 'iq', ...
                        'iq (Amps)', ...
                        [], false, [], plot_struct);

  % i_q, i_q,cmd
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'iq, iq command', {'iq', 'iq_cmd'}, ...
                        'iq, iq_{cmd} (Amps)', ...
                        [], false, [], plot_struct);

  % i_d
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'id', 'id', ...
                        'id (Amps)', ...
                        [], false, [], plot_struct);

  % i_d, i_d,cmd
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'id, id command', {'id', 'id_cmd'}, ...
                        'id, id_{cmd} (Amps)', ...
                        [], false, [], plot_struct);

  % imag, imag_cmd *** Note: the order here matters to make sure precursors are
  % calculated
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], '|i|', 'imag', ...
                        '|i| (Amps)', {'@(x,y) hypot(x, y)', {'id', 'iq'}, ...
                        'imag', []}, false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], '|i| command', 'imag_cmd', ...
                        '|i| (Amps)', {'@(x,y) hypot(x, y)', {'id_cmd', 'iq_cmd'}, ...
                        'imag_cmd', []}, false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], '|i|, |i| command', {'imag', 'imag_cmd'}, ...
                        '|i|, |i| command', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        1, '|i| error (Filtered)', 'imag_err', ...
                        '|i| error (Amps)', {'@(x,y) x - y', {'imag_cmd', 'imag'}, ...
                        'imag_err', []}, false, [], plot_struct);

  % Voltage
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Vq', 'vq', ...
                        'Vq (V)', [], false, [], plot_struct);

  % Voltage
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Vd', 'vd', ...
                        'Vd (V)', ...
                        [], false, [], plot_struct);

  % Bus Current
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Bus Current', 'bus_current', ...
                        'Bus Current (Amps)', ...
                        [], false, [], plot_struct);

  % Bus Current changiness
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        7, 'abs(Bus Current diff)', 'bus_current', ...
                        'Current Delta (Amps)', ...
                        [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'kt scale factor', 'kt_scale', ...
                        'kt', ...
                        [], false, [], plot_struct);

  % Stack bus currents
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        2, 'Bus Current Sums', 'bus_current', ...
                        'Bus Curent (Amps)', ...
                        [], false, [], plot_struct);

  % Aio Sequence numbers
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Aio Sequence Number Data', 'aioseq', ...
                        'Sequence Number', ...
                        {'@(x) x', 'sequence', ...
                        'aioseq', 'aio_header'}, false, [], plot_struct);
end % End high_speed

if (contains({'high_speed','sequence','alignfault','all'}, plot_str))
  % Sequence numbers
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        2, 'Sequence deltas motor', 'sequence', ...
                        'Count', [], true, [], plot_struct);

  % Received counter
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        2, 'Motor packet gaps', 'counter', ...
                        'Count Diff', {'@(x) x', 'counter', ...
                        'counter', ''}, false, [], plot_struct);

  % Sequence numbers
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Motor Sequence Data', 'sequence', ...
                        'Count', [], false, [], plot_struct);

  % Timing deltas
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        2, 'Diff Timing', 'capture_time', ...
                        'Sample Delta (sec)', [], false, [], plot_struct);
end % High speed and sequence plots

% Apply a correction for spin direction to parameters, making it easier to
% compare motors head to head.
if (contains({'spin_corrected'}, plot_str))

  %% Generate high speed Plots
  % Motor status

  % Voltage
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Voltage', 'bus_voltage', 'Voltage (V)', ...
                        [], false, [], plot_struct);

  % Voltage mean for stacking
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Voltage Mean', 'voltage_stack_mean', ...
                        'Voltage (V)', [], false, [], plot_struct);

  % Voltage Sum
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        [], 'Voltage Sum', 'bus_voltage', 'Voltage (V)', ...
                        [], false, [], plot_struct);

  % Voltage diff
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        7, '|Voltage diff| filtered', 'bus_voltage', 'Voltage (V)', ...
                        [], false, [], plot_struct);

  % Voltage mean diff for stacking
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        7, '|Voltage Mean diff|', 'voltage_stack_mean', ...
                        '|Voltage (V)|', [], false, [], plot_struct);

  % Bus Current
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Bus Current', 'bus_current', ...
                        'Bus Current (Amps)', ...
                        [], false, [], plot_struct);

  % Bus Current abs diff
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        7, '|Bus Current diff| filtered', 'bus_current', ...
                        'Bus Current (Amps)', ...
                        [], false, [], plot_struct);

  % Voltage Chassis
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Chassis Voltage', 'chassis_voltage', 'Voltage (V)', ...
                        [], false, [], plot_struct);

  % Voltage CM
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'CM Voltage', 'cm_voltage', 'Voltage (V)', ...
                        [], false, [], plot_struct);


  % Speed
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], '|Speed|', 'abs_omega', 'Omega (rad/sec)', ...
                        {'@(x) abs(x)', {'omega'}, ...
                        'abs_omega', []}, false, [], plot_struct);

  % Plot individual powers
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Motor Power (Filtered at 10 Hz)', 'power', ...
                        'Power (W)', {'@(x,y) x.*y', {'bus_voltage', 'bus_current'}, ...
                        'power', []}, false, [], plot_struct);

  % Power Sum
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        3, 'Power Sum (Filtered at 20 Hz)', 'power', ...
                        'Power (W)', {'@(x,y) x.*y', {'bus_voltage', 'bus_current'}, ...
                        'power', []}, false, [], plot_struct);

  % Power Sum (unfiltered)
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        8, 'Power Sum', 'power', ...
                        'Power (W)', [], false, [], plot_struct);

  % Power Sum rate
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        7, 'Power Sum Rate (Filtered at 1 Hz)', 'power', ...
                        'Power (W/sec)', {'@(x,y) x.*y', {'bus_voltage', 'bus_current'}, ...
                        'power', []}, false, [], plot_struct);

  % Motor pair bias correction
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Voltage Pair Bias', 'voltage_pair_bias', ...
                        'Voltage (V)', [], false, [], plot_struct);

  % Generate abs_omega_upper_limit for later plot
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'GenerateOnly', ...
                        [], '', '', ...
                        '', {'@(x) abs(x)', 'omega_upper_limit', ...
                        'abs_omega_upper_limit', []}, false, [], plot_struct);

  % Plot upper and lower speed commands on the same plot
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], '|Speed Command|', ...
                        {'abs_omega_upper_limit', 'abs_omega_lower_limit'}, ...
                        '|Speed Command| (rad/sec)', ...
                        {'@(x) abs(x)', 'omega_lower_limit', ...
                        'abs_omega_lower_limit', []}, false, [], plot_struct);

  % Speed sum (cross pair differences)
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        2, 'Difference in pair speed commands', 'omega_upper_limit', ...
                        'Speed Command (rad/sec)', [], false, [], plot_struct);

  % Spin corrected speed correction
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Speed Correction', 'speed_correction', ...
                        'Speed Correction (rad/sec)', ...
                        {'@(x,y) x .* sign(y)', {'speed_correction', ...
                        'omega_upper_limit'}, 'speed_correction', []}, ...
                        false, [], plot_struct);

  % Stacking current correction
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Current Correction', 'current_correction', ...
                        'Current (A)', ...
                        [], false, [], plot_struct);

  % Iq command residual
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'iq (command residual)', 'iq_cmd_residual', ...
                        'i_q (A)', ...
                        [], false, [], plot_struct);

  % Calculated ibus upper limit
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'i_{bus} (upper limit)', 'iq_upper_limit', ...
                        'i_{bus} (Amps)', ...
                        [], false, [], plot_struct);

  % Calculated ibus lower limit
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'i_{bus} (lower limit)', 'iq_lower_limit', ...
                        'i_{bus} (Amps)', ...
                        [], false, [], plot_struct);

  % spin corrected i_q, i_q,cmd
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'GenerateOnly', ...
                        [], '', '', ...
                        '', {'@(x,y) x .* sign(y)', {'iq', 'omega_upper_limit'}, ...
                        'iq_p', []}, false, [], plot_struct);

  % Iq and Iq_cmd
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'iq, iq command', {'iq_p', 'iq_cmd_p'}, ...
                        'iq, iq_{cmd} (Amps)', ...
                        {'@(x,y) x .* sign(y)', {'iq_cmd', 'omega_upper_limit'}, ...
                        'iq_cmd_p', []}, false, [], plot_struct);

  % Plot of sum of torques
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorSumData', ...
                        3, 'Torque Sum (filtered)', 'iq_x_kt', ...
                        'X Moment Sum (N)', {'@(x) x * 1.5 * 15 * .16666 * .9', ...
                        'iq', 'iq_x_kt', []}, false, [], plot_struct);

  % i_cmd without current correction
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'iq - current correction', 'iq_raw', ...
                        'iq raw (Amps)', ...
                        {'@(x,y) x - y', {'iq_cmd_p', 'current_correction'}, ...
                        'iq_raw', []}, false, [], plot_struct);
  % i_d, i_d,cmd
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'id, id command', {'id', 'id_cmd'}, ...
                        'id, id_{cmd} (Amps)', ...
                        [], false, [], plot_struct);

  % imag *** Note: the order here matters to make sure precursors are
  % calculated
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], '|i|', 'imag', ...
                        '|i| (Amps)', {'@(x,y) hypot(x, y)', {'id', 'iq'}, ...
                        'imag', []}, false, [], plot_struct);

  % A measure of the current error
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        1, '|i error|', 'i_error_mag', ...
                        '|i error| (Amps)', ...
                        {'@(a,b,c,d) hypot(a - b, c - d)', ...
                        {'id', 'id_cmd', 'iq', 'iq_cmd'}, ...
                        'i_error_mag', []}, false, [], plot_struct);

  % Spin corrected voltage
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Vq', 'vq', ...
                        'Vq (V)', ...
                        {'@(x,y) x .* sign(y)', {'vq', 'omega_upper_limit'}, ...
                        'vq', []}, false, [], plot_struct);

  % Voltage
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'Vd', 'vd', ...
                        'Vd (V)', ...
                        [], false, [], plot_struct);

  % Kt scaling
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], 'kt scale factor', 'kt_scale', ...
                        'kt', ...
                        [], false, [], plot_struct);

end % End high_speed

if (contains({'angle_sensor'}, plot_str))

  %% Plot omega for reference
  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        [], '|Speed|', 'abs_omega', 'Omega (rad/sec)', ...
                        {'@(x) abs(x)', {'omega'}, ...
                        'abs_omega', []}, false, [], plot_struct);

  %% Generate subcommutated high speed Plots

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        8, 'sin scale', {'angle_sensor.i_sin', ...
                        'angle_sensor.sin_scale'}, ...
                        'counts', ...
                        [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        8, 'sin offset', {'angle_sensor.i_sin', ...
                        'angle_sensor.sin_offset'}, ...
                        'counts', ...
                        [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        8, 'cos scale', {'angle_sensor.i_cos', ...
                        'angle_sensor.cos_scale'}, ...
                        'counts', ...
                        [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorDebug', 'PlotMotorData', ...
                        8, 'cos offset', {'angle_sensor.i_cos', ...
                        'angle_sensor.cos_offset'}, ...
                        'counts', ...
                        [], false, [], plot_struct);

end % End subcom

if (contains({'low_speed', 'status', 'all', 'temp', 'temperature'}, plot_str))

  if (contains({'low_speed', 'status', 'all'}, plot_str))
    % Plot low speed data (100 Hz)
    % Speed
    plot_struct = BuildPlotStruct('kMessageTypeMotorStatus', 'PlotMotorData', ...
                        [], 'Speed 100 Hz Data', 'omega', ...
                        'Omega (rad/sec)', [], false, [], plot_struct);

  	% Speed Command
    plot_struct = BuildPlotStruct('kMessageTypeMotorStatus', 'PlotMotorData', ...
                        [], 'Speed Command 100 Hz Data', ...
                        {'omega_upper_limit', 'omega_lower_limit'}, ...
                        'Omega Command(rad/sec)', [], false, [], plot_struct);

    % Torque Command
    plot_struct = BuildPlotStruct('kMessageTypeMotorStatus', 'PlotMotorData', ...
                        [], 'Torque Command 100 Hz Data', 'torque_cmd', ...
                        'Torque Command (Nm)', [], false, [], plot_struct);

    % Current
    plot_struct = BuildPlotStruct('kMessageTypeMotorStatus', 'PlotMotorData', ...
                        [], 'Q Current 100 Hz Data', ...
                        {'iq', 'iq_cmd'}, ...
                        'iq, iq_cmd (Amps)', [], false, [], plot_struct);

    % D Current
    plot_struct = BuildPlotStruct('kMessageTypeMotorStatus', 'PlotMotorData', ...
                        [], 'D Current 100 Hz Data', ...
                        {'id', 'id_cmd'}, ...
                        'id, id_cmd (Amps)', [], false, [], plot_struct);

    % Bus Voltage
    plot_struct = BuildPlotStruct('kMessageTypeMotorStatus', 'PlotMotorData', ...
                        [], 'Bus Voltage 100 Hz Data', 'bus_voltage', ...
                        'Bus Voltage (Volts)', [], false, [], plot_struct);

    % Bus Current
    plot_struct = BuildPlotStruct('kMessageTypeMotorStatus', 'PlotMotorData', ...
                        [], 'Bus Current 100 Hz Data', 'bus_current', ...
                        'Bus Current (Amps)', [], false, [], plot_struct);

    % Temperature data
    plot_struct = BuildPlotStruct('kMessageTypeMotorStatus', 'PlotMotorTempData', ...
                        [], 'Temperature plots', 'temps', ...
                        'DegC', [], true, [], plot_struct);

    % Aio Sequence numbers
    plot_struct = BuildPlotStruct('kMessageTypeMotorStatus', 'PlotMotorData', ...
                        [], 'Sequence Number 100 Hz Data', 'sequence', ...
                        'Sequence Number', {'@(x) x', 'sequence', ...
                        'aioseq', 'aio_header'}, false, [], plot_struct);
  end
end % Status message

if (contains({'low_voltage','all'}, plot_str))

  %% Plot low speed data (100 Hz)
  % Voltages and current
  plot_struct = BuildPlotStruct('kMessageTypeMotorStatus', 'PlotMotorArrayData', ...
                      [], 'LV Voltage', 'motor_mon.ina219_data.voltage', ...
                      'Voltage (V)', [], true, {'12V','1.2V','3.3V'}, plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeMotorStatus', 'PlotMotorArrayData', ...
                      [], 'LV Current', 'motor_mon.ina219_data.current', ...
                      'Current (Amps)', [], true, {'12V','1.2V','3.3V'}, plot_struct);

end % LV power (in status_message message



if (contains({'slow_status', 'all'}, plot_str))
  % Extract low speed messages

  %% TMS570 Network Status

  % Aio Received Valid Packets
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Aio Received Valid Packets', ...
                      'network_status.aio_stats.received_valid_aio_packets', ...
                      'Valid Packets (counts)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Aio Received Invalid Packets', ...
                      'network_status.aio_stats.received_invalid_aio_packets', ...
                      'Invalid Packets (counts)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Aio Received Non Routine Packets', ...
                      'network_status.aio_stats.received_non_routine_packets', ...
                      'Non Routine Packets (counts)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Aio Received ARP Request Packets', ...
                      'network_status.aio_stats.received_arp_request_packets', ...
                      'ARP Request Packets (counts)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Aio Received ICMP Request Packets', ...
                      'network_status.aio_stats.received_icmp_request_packets', ...
                      'ICMP Request Packets (counts)', [], false, [], plot_struct);

  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Aio Received Probe Packets', ...
                      'network_status.aio_stats.received_probe_packets', ...
                      'Probe Packets (counts)', [], false, [], plot_struct);

  % Aio Sent Packets
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Aio Sent Packets', ...
                      'network_status.aio_stats.sent_aio_packets', ...
                      'Sent Packets (counts)', [], false, [], plot_struct);

  % Cvt Unique Packets
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Cvt Unique Packets', ...
                      'network_status.cvt_stats.unique_packets', ...
                      'Unique Packets (counts)', [], false, [], plot_struct);

  % Cvt Unread Packets
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Cvt Unread Packets', ...
                      'network_status.cvt_stats.unread_packets', ...
                      'Unread Packets (counts)', [], false, [], plot_struct);

  % Cvt Invalid Packets
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Cvt Invalid Packets', ...
                      'network_status.cvt_stats.invalid_packets', ...
                      'Invalid Packets (counts)', [], false, [], plot_struct);

  % Cvt Event Codes
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Cvt Event Codes', ...
                      'network_status.cvt_stats.event_codes', ...
                      'Events (codes)', [], false, [], plot_struct);

  %% CoreSwitch (? Hz)

  % ethernet_stats
  % Rx Stats
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Rx Multicast Packet Rate', ...
                      'switch_stats.stats.rx_multicast_packet_rate', ...
                      'Rx Rate (counts)', [], false, [], plot_struct);

  % Tx Stats
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Tx Multicast Packet Rate', ...
                      'switch_stats.stats.tx_multicast_packet_rate', ...
                      'Tx Rate (counts)', [], false, [], plot_struct);

  % Rx Octet Rates
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Rx Octet Rate', ...
                      'switch_stats.stats.rx_octet_rate', ...
                      'Rx Rate (counts)', [], false, [], plot_struct);

  % Tx Octet Rates
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Tx Octet Rate', ...
                      'switch_stats.stats.tx_octet_rate', ...
                      'Tx Rate (counts)', [], false, [], plot_struct);

  % Rx Fragment Error
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Rx Fragment Rate', ...
                      'switch_stats.stats.rx_fragment_errors', ...
                      'Rx Fragments (counts)', [], false, [], plot_struct);

  % Rx Alignment Error
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Rx Alignment Errors', ...
                      'switch_stats.stats.rx_alignment_errors', ...
                      'Rx Alignment (counts)', [], false, [], plot_struct);

  % Rx FCS Error
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Rx FCS Errors', ...
                      'switch_stats.stats.rx_fcs_errors', ...
                      'Rx FCS (counts)', [], false, [], plot_struct);

  % Rx Symbol Error
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Rx Symbol Errors', ...
                      'switch_stats.stats.rx_symbol_errors', ...
                      'Rx Symbols (counts)', [], false, [], plot_struct);

  % Rx Jabber Error
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Rx Jabber Errors', ...
                      'switch_stats.stats.rx_jabber_errors', ...
                      'Rx Jabbers (counts)', [], false, [], plot_struct);

  % Rx In Range Error
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Rx In Range Errors', ...
                      'switch_stats.stats.rx_in_range_errors', ...
                      'Rx In Range Errors (counts)', [], false, [], plot_struct);

  % Rx Good Octet Rate
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Rx Good Octet Rate', ...
                      'switch_stats.stats.rx_good_octet_rate', ...
                      'Rx Good Octet Rate (counts)', [], false, [], plot_struct);

  % Tx Dropped Packets
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Tx Dropped Packets', ...
                      'switch_stats.stats.tx_dropped_packets', ...
                      'Tx Dropped Packets (counts)', [], false, [], plot_struct);

  % Link Status Bits
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Link Status Bits', ...
                      'switch_stats.link_status_bits', ...
                      'Status Bits', [], false, [], plot_struct);

  % Seq Number
  plot_struct = BuildPlotStruct('kMessageTypeSlowStatus', 'PlotMotorData', ...
                      [], 'Eth Sequence Number', ...
                      'switch_stats.sequence_num', ...
                      'Seq Num (counts)', [], false, [], plot_struct);

  % Aio Sequence numbers
  plot_struct = BuildPlotStruct('kMessageTypeSlotStatus', 'PlotMotorData', ...
                      [], 'Sequence Number 1 Hz Data', 'sequence', ...
                      'Sequence Number', {'@(x) x', 'sequence', ...
                      'aioseq', 'aio_header'}, false, [], plot_struct);

end % Low speed
end
